﻿using ff14bot;
using ff14bot.Managers;
using ff14bot.Enums;
using MoreDots.Rotations.Classes;
using MoreDots.SpellNames.Jobs;
using System.Threading.Tasks;
using System.Collections.Generic;
using Buddy.Coroutines;
using ff14bot.Objects;
using System.Linq;

namespace MoreDots.Rotations.Jobs
{
    public class Summoner : Arcanist
    {
        public override string Name { get { return "MoreDots [" + GetType().Name + "]"; } }
        public override ClassJobType[] Class { get { return new ClassJobType[] { ClassJobType.Summoner }; } }

        public override async Task<bool> CombatLvL1()
        {
            return await SummonerSpells.Ruin.Cast();
        }

        public override async Task<bool> CombatLvL2()
        {
            if (!Helpers.HasAura(Core.Player.CurrentTarget, SummonerSpells.Bio.Name, false, 2000))
            {
                await SummonerSpells.Bio.Cast();
            }
            return await SummonerSpells.Ruin.Cast();
        }

        public override async Task<bool> CombatLvL50()
        {
            if (await Aetherflow()) return true;
            if (await Fester()) return true;
            if (await SummonerSpells.CrossClass.RagingStrikes.Buff()) return true;
            if (await Bane()) return true;
            if (await BioII()) return true;
            if (await Miasma()) return true;
            if (await Bio()) return true;
            if (await MiasmaII()) return true;
            if (await Shadowflare()) return true;
            if (await Rouse()) return true;
            if (await Spur()) return true;
            return await Ruin();
        }

        #region Combat Spells

        public async Task<bool> MiasmaII()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            if (Helpers.HasAura(Core.Player, SummonerSpells.CrossClass.RagingStrikes.Name, true, 1) && Core.Player.CurrentTarget.Location.Distance(Core.Player.Location) <= 5)
            {
                return await SummonerSpells.MiasmaII.Buff();
            }
            return false;
        }

        public async Task<bool> RagingStrikes()
        {
            return await SummonerSpells.CrossClass.RagingStrikes.Buff();
        }

        public async Task<bool> Rouse()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            if (Actionmanager.CanCast(SummonerSpells.Rouse.Name, Core.Player))
            {
                return await SummonerSpells.Rouse.Buff();
            }
            return false;
        }

        public async Task<bool> Spur()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            if (Actionmanager.CanCast(SummonerSpells.Spur.Name, Core.Player))
            {
                return await SummonerSpells.Spur.Buff();
            }
            return false;
        }

        public async Task<bool> Aetherflow()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            var hasAura = !Core.Player.HasAura(SummonerSpells.Aetherflow.Name) &&
                            Actionmanager.CanCast(SummonerSpells.Aetherflow.Name, Core.Player);
            if (hasAura == true)
            {
                if (await SummonerSpells.RuinII.Cast())
                {
                    await Coroutine.Wait(3000, () => Actionmanager.CanCast(SummonerSpells.Aetherflow.Name, Core.Player));
                    return await SummonerSpells.Aetherflow.Buff();
                }
                return false;
            }
            return false;
        }

        public async Task<bool> Fester()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            var auras = new List<string> { SummonerSpells.BioII.Name, SummonerSpells.Miasma.Name, SummonerSpells.Bio.Name };
            var hasAuras = Helpers.HasAura(Core.Player.CurrentTarget, auras.ToArray(), true, 2000) &&
                            Core.Player.HasAura(SummonerSpells.Aetherflow.Name) &&
                            Actionmanager.CanCast(SummonerSpells.Fester.Name, Core.Player.CurrentTarget);

            if (hasAuras)
            {
                if (await SummonerSpells.RuinII.Cast())
                {
                    await Coroutine.Wait(3000, () => Actionmanager.CanCast(SummonerSpells.Fester.Name, Core.Player.CurrentTarget));
                    return await SummonerSpells.Fester.Cast();
                }
                return false;
            }
            return false;
        }

        public async Task<bool> Bane()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }

            var auras = new List<string> { SummonerSpells.BioII.Name, SummonerSpells.Miasma.Name, SummonerSpells.Bio.Name };

            int targets = GameObjectManager.GetObjectsOfType<BattleCharacter>().Count(r =>
                r.Distance(Core.Player.CurrentTarget) <= 8 &&
                !Helpers.HasAura(r, auras.ToArray(), true));
            
            if (
                Helpers.EnemiesNearTarget(8) > 1 &&
                Helpers.HasAura(Core.Player.CurrentTarget, auras.ToArray(), true, 10000) &&
                Core.Player.HasAura(SummonerSpells.Aetherflow.Name) && targets > 1 &&
                Actionmanager.CanCast(SummonerSpells.Bane.Name, Core.Player.CurrentTarget)
                )
            {
                if (await SummonerSpells.RuinII.Cast())
                {
                    await Coroutine.Wait(3000, () => Actionmanager.CanCast(SummonerSpells.Bane.Name, Core.Player.CurrentTarget));
                    return await SummonerSpells.Bane.Cast();
                }
                return false;
            }
            return false;
        }

        public async Task<bool> BioII()
        {
            if (Core.Player.IsCasting || MovementManager.IsMoving)
            {
                return true;
            }
            if (!Helpers.HasAura(Core.Player.CurrentTarget, SummonerSpells.BioII.Name, true, 2000))
            {
                if (await SummonerSpells.BioII.Cast())
                {
                    await Coroutine.Wait(8000, () => Core.Player.CurrentTarget.HasAura(SummonerSpells.BioII.Name, true, 22000) || MovementManager.IsMoving);
                    return true;
                }
            }
            return false;
        }

        public async Task<bool> Miasma()
        {
            if (Core.Player.IsCasting || MovementManager.IsMoving)
            {
                return true;
            }
            if (!Helpers.HasAura(Core.Player.CurrentTarget, SummonerSpells.Miasma.Name, true, 4000))
            {
                if (await SummonerSpells.Miasma.Cast())
                {
                    await Coroutine.Wait(8000, () => Core.Player.CurrentTarget.HasAura(SummonerSpells.Miasma.Name, true, 20000) || MovementManager.IsMoving);
                    return true;
                }
            }
            return false;
        }

        public async Task<bool> Bio()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            if (!Helpers.HasAura(Core.Player.CurrentTarget, SummonerSpells.Bio.Name, true, 2000))
            {
                if (await SummonerSpells.Bio.Cast())
                {
                    await Coroutine.Wait(5000, () => Core.Player.CurrentTarget.HasAura(SummonerSpells.Bio.Name, true, 15000));
                    return true;
                }
            }
            return false;
        }

        public async Task<bool> Shadowflare()
        {
            if (Core.Player.IsCasting)
            {
                return true;
            }
            if (!Helpers.HasAura(Core.Player, SummonerSpells.ShadowFlare.Name, true, 2000) && Actionmanager.CanCast(SummonerSpells.CrossClass.Swiftcast.Name, Core.Player))
            {
                if (await SummonerSpells.CrossClass.Swiftcast.Buff())
                {
                    await Coroutine.Wait(2000, () => false);

                    if (await SummonerSpells.ShadowFlare.CastOnLocation())
                    {
                        await Coroutine.Wait(5000, () => Core.Player.HasAura(SummonerSpells.ShadowFlare.Name));
                        return true;
                    }
                }
            }

            if (MovementManager.IsMoving)
            {
                return true;
            }

            if (!Helpers.HasAura(Core.Player, SummonerSpells.ShadowFlare.Name, true, 2000) && !Actionmanager.CanCast(SummonerSpells.CrossClass.Swiftcast.Name, Core.Player))
            {
                if (await SummonerSpells.ShadowFlare.CastOnLocation())
                {
                    await Coroutine.Wait(5000, () => Core.Player.HasAura(SummonerSpells.ShadowFlare.Name) || MovementManager.IsMoving);
                    return true;
                }
            }
            return false;
        }

        public async Task<bool> Ruin()
        {
            if (Core.Player.IsCasting || MovementManager.IsMoving)
            {
                return true;
            }
            return await SummonerSpells.Ruin.Cast();
        }

        #endregion

    }
}

